package com.siemens.industrial.web.mvc.service.admin;

import com.siemens.industrial.model.admin.Tenant;
import com.siemens.industrial.web.mvc.dao.admin.ChartsDao;
import com.siemens.industrial.web.mvc.dao.admin.TenantDao;
import com.siemens.industrial.web.mvc.dao.partner.PartnerDeviceShiftRelationDao;
import com.siemens.industrial.web.mvc.service.partner.PartnerShiftService;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by shuan on 2016/11/15.
 */
@Service
public class ChartsService {
    @Resource
    ChartsDao chartsDao;

    @Resource
    JdbcTemplate jdbcTemplate;

    @Resource
    TenantDao tenantDao;

    @Resource
    PartnerDeviceShiftRelationDao partnerDeviceShiftRelationDao;

    //获取租户的所有设备列表
    public List getDevicesByTenantId(String database) {
        return chartsDao.getDevicesByTenantId(database);
    }

    //查询所有机床oee或availability或performance或quality的top10
    public Map getAllDeviceTop(String day) {
//        String date = "2016-11-24";
        Map map = new HashMap<>();

        List<Map<String, Object>> tenants = chartsDao.getTenants();
        if (tenants.size() == 0) {
            return null;
        }
        //(原 可选)    chartsDao.getDeviceRank
        //oee前10排名
        List oeeTopAsc = chartsDao.findDeviceRankNew(tenants, "oee", day, "desc");
        //performance前10排名
        List performanceTopAsc = chartsDao.findDeviceRankNew(tenants, "performance", day, "desc");
        //availability前10排名
        List availabilityTopAsc = chartsDao.findDeviceRankNew(tenants, "availability", day, "desc");
        //quality前10排名
        List qualityTopAsc = chartsDao.findDeviceRankNew(tenants, "quality", day, "desc");

        //oee后10排名
        List oeeTopDesc = chartsDao.findDeviceRankNew(tenants, "oee", day, "asc");
        //performance后10排名
        List performanceTopDesc = chartsDao.findDeviceRankNew(tenants, "performance", day, "asc");
        //availability后10排名
        List availabilityTopDesc = chartsDao.findDeviceRankNew(tenants, "availability", day, "asc");
        //quality后10排名
        List qualityTopDesc = chartsDao.findDeviceRankNew(tenants, "quality", day, "asc");
        map.put("oeeTopAsc", oeeTopAsc);
        map.put("performanceTopAsc", performanceTopAsc);
        map.put("availabilityTopAsc", availabilityTopAsc);
        map.put("qualityTopAsc", qualityTopAsc);
        map.put("oeeTopDesc", oeeTopDesc);
        map.put("performanceTopDesc", performanceTopDesc);
        map.put("availabilityTopDesc", availabilityTopDesc);
        map.put("qualityTopDesc", qualityTopDesc);

        return map;
    }

    //获取全部租户设备根据type_model and device_model
    public List getDevicesByTypeAndModel(String deviceType, String deviceModel) {
        List<Tenant> tenants = tenantDao.getTenants();
        if (tenants.size() == 0) {
            return null;
        }
        return chartsDao.getDevicesByTypeAndModel(tenants, deviceType, deviceModel);
    }

    //获取oee或其他性能参数数据(原 可选)
    public List<Map<String, Object>> serviceCompare(ArrayList<Map<String, Object>> tenantAndDevice, String startTime, String endTime) throws ParseException {
        return chartsDao.getServiceCompare(tenantAndDevice, startTime, endTime);
    }

    //获取oee或其他性能参数数据(oee=availability)
    public List<Map<String, Object>> serviceCompareNew(ArrayList<Map<String, Object>> tenantAndDevice, String startTime, String endTime) throws ParseException {
        return chartsDao.getServiceCompareNew(tenantAndDevice, startTime, endTime);
    }

    public List<Map<String, Object>> getStateOfDay(List<Map<String, Object>> maps, String startTime, String endTime) {
        String sql = "";
        for (int i = 0; i < maps.size(); i++) {
            String sqlOfOne = "SELECT \n" +
                    "    f.date_id,\n" +
                    "    f.device_id,\n" +
                    "    f.on_line,\n" +
                    "    f.off_line,\n" +
                    "    g.device_unique_id\n" +
                    "FROM\n" +
                    "    (SELECT \n" +
                    "        a.date_id,\n" +
                    "            a.device_id,\n" +
                    "            IFNULL(b.on_line, 0) on_line,\n" +
                    "            IFNULL(b.off_line, 86400) off_line\n" +
                    "    FROM\n" +
                    "        (SELECT \n" +
                    "        date_id, '" + maps.get(i).get("deviceId") + "' device_id\n" +
                    "    FROM\n" +
                    "        `" + maps.get(i).get("tenantId") + "`.v_num\n" +
                    "    WHERE\n" +
                    "        date_id BETWEEN DATE('" + startTime + "') AND DATE('" + endTime + "')) a\n" +
                    "    LEFT JOIN (SELECT \n" +
                    "        device_id,\n" +
                    "            date_id,\n" +
                    "            SUM(CASE\n" +
                    "                WHEN state = 1 THEN `time_lag`\n" +
                    "                ELSE 0\n" +
                    "            END) AS on_line,\n" +
                    "            SUM(CASE\n" +
                    "                WHEN state = 0 THEN `time_lag`\n" +
                    "                ELSE 0\n" +
                    "            END) AS off_line\n" +
                    "    FROM\n" +
                    "        (SELECT \n" +
                    "        device_id,\n" +
                    "            DATE(start_time) date_id,\n" +
                    "            state,\n" +
                    "            SUM(TIMESTAMPDIFF(SECOND, start_time, end_time)) AS time_lag\n" +
                    "    FROM\n" +
                    "        `" + maps.get(i).get("tenantId") + "`.device_state_period\n" +
                    "    WHERE\n" +
                    "        start_time >= '" + startTime + "'\n" +
                    "            AND end_time <= '" + endTime + "'\n" +
                    "            AND (device_id = '" + maps.get(i).get("deviceId") + "')\n" +
                    "    GROUP BY device_id , date_id , state) a\n" +
                    "    GROUP BY device_id , date_id\n" +
                    "    ORDER BY date_id) b ON a.date_id = b.date_id\n" +
                    "        AND a.device_id = b.device_id) f\n" +
                    "        LEFT JOIN\n" +
                    "    `" + maps.get(i).get("tenantId") + "`.device g ON f.device_id = g.device_id";

            if (i != maps.size() - 1) {
                sqlOfOne = sqlOfOne + " UNION ALL ";
            }

            sql += sqlOfOne;
        }

        if (sql.equals(""))
            return new ArrayList<>();

        sql += "\norder by date_id";
        System.out.print(sql);
        return jdbcTemplate.queryForList(sql);
    }

    public Map<String, List<Map<String, Object>>> stateBuild(Map<String, Object> data) {
        String startTime = data.get("startTime").toString();
        String endTime = data.get("endTime").toString();
        List<Map<String, Object>> list = (List<Map<String, Object>>) data.get("tenantAndDevice");
        List<Map<String, Object>> maps = this.getStateOfDay(list, startTime, endTime);

        Map<String, List<Map<String, Object>>> deviceStateList = deviceStateChartDataFormat(maps);
        return deviceStateList;
    }

    //admin partner get device state chart data Format
    public Map<String, List<Map<String, Object>>> deviceStateChartDataFormat(List<Map<String, Object>> maps) {

        Map<String, Object> one = maps.get(0);
        List<Map<String, Object>> mapList = new ArrayList<>();
        List<Map<String, Object>> series = new ArrayList<>();
        for (Map<String, Object> map : maps) {
            if (map.get("date_id").equals(one.get("date_id"))) {
                Map<String, Object> seriesOfOnLine = new HashMap<>();
                Map<String, Object> seriesOfOffLine = new HashMap<>();
                seriesOfOnLine.put("valueField", map.get("device_id").toString() + "on");
                seriesOfOffLine.put("valueField", map.get("device_id").toString() + "off");
                seriesOfOnLine.put("name", map.get("device_unique_id") + "在线");
                seriesOfOffLine.put("name", map.get("device_unique_id") + "离线");
                seriesOfOnLine.put("stack", map.get("device_id"));
                seriesOfOffLine.put("stack", map.get("device_id"));
                seriesOfOnLine.put("color", "#ba4751");
                seriesOfOffLine.put("color", "#5f8b95");
                series.add(seriesOfOffLine);
                series.add(seriesOfOnLine);
            }
            Map<String, Object> newMap = new HashMap<>();
            newMap.put("date_id", map.get("date_id"));
            newMap.put(map.get("device_id").toString() + "off", map.get("off_line"));
            newMap.put(map.get("device_id").toString() + "on", map.get("on_line"));
            mapList.add(newMap);
        }
        return new HashMap<String, List<Map<String, Object>>>() {{
            put("dataSource", mapList);
            put("series", series);
        }};
    }

    //shift oee 对比 一段时间(oee=availability) 小时显示
    public List<Map<String, Object>> getShiftService(ArrayList<Map<String, Object>> tenantAndDevice, String day, String type) {
        try {
            List<Map<String, Object>> serviceList = chartsDao.findShiftServiceNew(tenantAndDevice, day);
            return serviceList;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    //获取某班次 performance availability quality oee数据(更换插件)
    public List<Map<String, Object>> getServiceByShift(ArrayList<Map<String, Object>> tenantAndDevice, String day, String type) {
        try {
            List<Map<String, Object>> dataSource = new ArrayList<>();
            List<Map<String, Object>> serviceList = chartsDao.findServiceByShiftNew(tenantAndDevice, day);
            List<Map<String, Object>> devices = chartsDao.findDeviceNameById(tenantAndDevice);

            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            for (int i = 0; i < devices.size(); i++) {
                Map serie = new HashMap<>();
                Map<String, Object> device = devices.get(i);

                ArrayList<ArrayList> datas = new ArrayList();
                for (int j = 0; j < serviceList.size(); j++) {
                    ArrayList data = new ArrayList();
                    if (device.get("device_id").equals(serviceList.get(j).get("device_id"))) {
                        data.add(sdf.parse(String.valueOf(serviceList.get(j).get("shift_start_time"))).getTime() + 28800000);
                        data.add(new BigDecimal(100).multiply((BigDecimal) serviceList.get(j).get(type)).doubleValue());
                        datas.add(data);
                    }
                    if (device.get("device_id").equals(serviceList.get(j).get("device_id")) && (!day.equals(serviceList.get(j).get("shift_end_time").toString().split(" ")[0]))) {
                        ArrayList endTimeData = new ArrayList();
                        endTimeData.add(sdf.parse(String.valueOf(serviceList.get(j).get("shift_end_time"))).getTime() + 28800000);
                        endTimeData.add(new BigDecimal(100).multiply((BigDecimal) serviceList.get(j).get(type)).doubleValue());
                        datas.add(endTimeData);
                    }
                }

                serie.put("name", device.get("deviceName"));
                serie.put("data", datas);
                dataSource.add(serie);
            }
            return dataSource;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}